home *** CD-ROM | disk | FTP | other *** search
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
-
- cr.define('cr.ui', function() {
- /**
- * A class to manage grid of focusable elements in a 2D grid. For example,
- * given this grid:
- *
- * focusable [focused] focusable (row: 0, col: 1)
- * focusable focusable focusable
- * focusable focusable focusable
- *
- * Pressing the down arrow would result in the focus moving down 1 row and
- * keeping the same column:
- *
- * focusable focusable focusable
- * focusable [focused] focusable (row: 1, col: 1)
- * focusable focusable focusable
- *
- * And pressing right at this point would move the focus to:
- *
- * focusable focusable focusable
- * focusable focusable [focused] (row: 1, col: 2)
- * focusable focusable focusable
- *
- * @param {Node=} opt_boundary Ignore focus events outside this node.
- * @param {cr.ui.FocusRow.Observer=} opt_observer An observer of rows.
- * @implements {cr.ui.FocusRow.Delegate}
- * @constructor
- */
- function FocusGrid(opt_boundary, opt_observer) {
- /** @type {Node|undefined} */
- this.boundary_ = opt_boundary;
-
- /** @private {cr.ui.FocusRow.Observer|undefined} */
- this.observer_ = opt_observer;
-
- /** @type {!Array.<!cr.ui.FocusRow>} */
- this.rows = [];
- }
-
- FocusGrid.prototype = {
- /**
- * Unregisters event handlers and removes all |this.rows|.
- */
- destroy: function() {
- this.rows.forEach(function(row) { row.destroy(); });
- this.rows.length = 0;
- },
-
- /**
- * @param {EventTarget} target A target item to find in this grid.
- * @return {?{row: number, col: number}} A position or null if not found.
- */
- getPositionForTarget: function(target) {
- for (var i = 0; i < this.rows.length; ++i) {
- for (var j = 0; j < this.rows[i].items.length; ++j) {
- if (target == this.rows[i].items[j])
- return {row: i, col: j};
- }
- }
- return null;
- },
-
- /** @override */
- onKeydown: function(keyRow, e) {
- var rowIndex = this.rows.indexOf(keyRow);
- assert(rowIndex >= 0);
-
- var row = -1;
-
- if (e.keyIdentifier == 'Up')
- row = rowIndex - 1;
- else if (e.keyIdentifier == 'Down')
- row = rowIndex + 1;
- else if (e.keyIdentifier == 'PageUp')
- row = 0;
- else if (e.keyIdentifier == 'PageDown')
- row = this.rows.length - 1;
-
- if (!this.rows[row])
- return false;
-
- var colIndex = keyRow.items.indexOf(e.target);
- var col = Math.min(colIndex, this.rows[row].items.length - 1);
-
- this.rows[row].focusIndex(col);
-
- e.preventDefault();
- return true;
- },
-
- /** @override */
- onMousedown: function(row, e) {
- return false;
- },
-
- /**
- * @param {!Array.<!NodeList|!Array.<!Element>>} grid A 2D array of nodes.
- */
- setGrid: function(grid) {
- this.destroy();
-
- this.rows = grid.map(function(row) {
- return new cr.ui.FocusRow(row, this.boundary_, this, this.observer_);
- }, this);
-
- if (!this.getPositionForTarget(document.activeElement) && this.rows[0])
- this.rows[0].activeIndex = 0;
- },
- };
-
- return {
- FocusGrid: FocusGrid,
- };
- });
-